<template>
  <div>
    <div></div>



    <!-- 地图图表 -->
    <div class="mapShower">
      <h3>全国项目数量分布</h3>
      <MapContainer v-if="ShowMap" />
    </div>

    <!-- 项目数量折线图 -->

    <div class="number_data">
      <h3>项目数量与日期折线关系图</h3>
      <div ref="lineChart" style="width: 1200px; height: 900px;"></div>
    </div>


    <div class="line_container">
      <div class="lineShower">
        <h3>条形图数据展示</h3>

        <ul style="display: flex; flex-wrap: wrap;" class="no-bullets">

          <li class="selectAll_check_box">
            <label>
              <input type="checkbox" v-model="selectAll1" @change="toggleAll" />
              全选
            </label>
          </li>

          <li v-for="(item, index) in items1" :key="index" style="margin-right: 20px;">
            <label>
              <input type="checkbox" v-model="item.checked" />
              {{ item.name }}
            </label>
          </li>
        </ul>

        <div class="lineShower_inner" ref="chart" style="width: 1400px; height: 600px;"></div>
      </div>
    </div>


    <div class="myChart_subSystem">
      <h3>各系统消费条形图</h3>
      <canvas id="myChart"></canvas>
    </div>
  </div>
</template>

<script>
import { onMounted, ref, reactive, watch } from 'vue';
import axios from 'axios';
import Chart from 'chart.js/auto'
import * as echarts from 'echarts';
import MapContainer from "@/components/MapContainer.vue"; // 导入地图组件
import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend } from 'chart.js';


export default {
  components: {
    MapContainer, // 注册地图组件
  },
  data() {
    return {
      items1: [
        { name: 'Apple', checked: false, number: 20 },
        { name: 'Banana', checked: true, number: 15 },
        { name: 'Cherry', checked: false, number: 30 },
        { name: 'Date', checked: true, number: 25 },
        { name: 'Elderberry', checked: false, number: 40 },
        { name: 'Fig', checked: true, number: 10 },
        { name: 'Grape', checked: true, number: 35 },
        { name: 'Honeydew', checked: false, number: 60 },
        { name: 'Indian Fig', checked: true, number: 50 },
        { name: 'Jackfruit', checked: false, number: 55 },
        { name: 'Kiwi', checked: true, number: 45 },
        { name: 'Lemon', checked: false, number: 20 },
        { name: 'Mango', checked: true, number: 75 },
        { name: 'Nectarine', checked: false, number: 18 },
        { name: 'Orange', checked: true, number: 28 },
        { name: 'Papaya', checked: false, number: 36 },
        { name: 'Quince', checked: true, number: 22 },
        { name: 'Raspberry', checked: false, number: 14 },
        { name: 'Strawberry', checked: true, number: 50 },
        { name: 'Tomato', checked: false, number: 5 },
        { name: 'Uva', checked: true, number: 70 },
        { name: 'Violet', checked: false, number: 12 },
        { name: 'Watermelon', checked: true, number: 80 },
        { name: 'Xigua', checked: false, number: 30 },
        { name: 'Yellow Passionfruit', checked: true, number: 60 },
        { name: 'Zucchini', checked: false, number: 25 },
        { name: 'Acerola', checked: true, number: 32 },
        { name: 'Blueberry', checked: false, number: 40 },
        { name: 'Cantaloupe', checked: true, number: 45 },
        { name: 'Dragonfruit', checked: false, number: 55 },
        { name: 'Elderberry', checked: true, number: 60 },
        { name: 'Fig', checked: false, number: 50 },
        { name: 'Guava', checked: true, number: 35 },
        { name: 'Huckleberry', checked: false, number: 20 },
        { name: 'Ita Palm', checked: true, number: 42 },
        { name: 'Jambolan', checked: false, number: 28 },
        { name: 'Kumquat', checked: true, number: 18 },
        { name: 'Lime', checked: false, number: 32 },
        { name: 'Mulberry', checked: true, number: 50 },
        { name: 'Nance', checked: false, number: 22 },
        { name: 'Olive', checked: true, number: 70 },
        { name: 'Peach', checked: false, number: 60 },
        { name: 'Pineapple', checked: true, number: 90 },
        { name: 'Plum', checked: false, number: 24 },
        { name: 'Pomegranate', checked: true, number: 10 },
        { name: 'Quince', checked: false, number: 32 },
        { name: 'Raisin', checked: true, number: 18 },
        { name: 'Salak', checked: false, number: 40 },
        { name: 'Soursop', checked: true, number: 55 },
        { name: 'Tamarillo', checked: false, number: 15 },
        { name: 'Tamarind', checked: true, number: 38 },
        { name: 'Uva', checked: false, number: 70 },
        { name: 'Vitis', checked: true, number: 44 },
        { name: 'Wolfberry', checked: false, number: 25 },
        { name: 'Xoconostle', checked: true, number: 10 },
        { name: 'Yangmei', checked: false, number: 30 },
        { name: 'Ziziphus', checked: true, number: 15 },
        { name: 'Apple', checked: false, number: 50 },
        { name: 'Banana', checked: true, number: 60 },
        { name: 'Carambola', checked: false, number: 20 },
        { name: 'Dragonfruit', checked: true, number: 30 },
        { name: 'Grapefruit', checked: false, number: 40 },
        { name: 'Fig', checked: true, number: 50 },
        { name: 'Guava', checked: false, number: 60 },
        { name: 'Jackfruit', checked: true, number: 70 },
        { name: 'Kiwi', checked: false, number: 30 },
        { name: 'Lemon', checked: true, number: 80 },
        { name: 'Lychee', checked: false, number: 55 },
        { name: 'Mango', checked: true, number: 20 },
        { name: 'Nectarine', checked: false, number: 30 },
        { name: 'Orange', checked: true, number: 45 },
        { name: 'Papaya', checked: false, number: 60 },
        { name: 'Pineapple', checked: true, number: 70 },
        { name: 'Quince', checked: false, number: 10 },
        { name: 'Raspberry', checked: true, number: 40 },
        { name: 'Strawberry', checked: false, number: 20 },
        { name: 'Tomato', checked: true, number: 50 },
        { name: 'Watermelon', checked: false, number: 75 },
        { name: 'Xigua', checked: true, number: 90 },
        { name: 'Yellow Passionfruit', checked: false, number: 15 },
        { name: 'Zucchini', checked: true, number: 35 },
        { name: 'Acerola', checked: false, number: 40 },
        { name: 'Blueberry', checked: true, number: 25 },
        { name: 'Cantaloupe', checked: false, number: 60 },
        { name: 'Dragonfruit', checked: true, number: 80 },
        { name: 'Elderberry', checked: false, number: 35 },
        { name: 'Fennel', checked: true, number: 45 },
        { name: 'Guava', checked: false, number: 15 },
        { name: 'Honeydew', checked: true, number: 60 },
        { name: 'Indian Fig', checked: false, number: 25 },
        { name: 'Jackfruit', checked: true, number: 55 },
        { name: 'Kiwi', checked: false, number: 10 },
        { name: 'Lemon', checked: true, number: 65 },
        { name: 'Mango', checked: false, number: 40 },
        { name: 'Nectarine', checked: true, number: 30 },
        { name: 'Orange', checked: false, number: 15 },
        { name: 'Papaya', checked: true, number: 50 }
      ],
      selectAll1: false,
      // 存储项目的名称
      projectNames: [],
      // 存储项目的子系统数据
      projectData: {},
      // 控制显示的子系统（目前不需要，除非你有其他显示控制）
      showSubs: {},
      // 用于保存图表的引用等信息
      chartData: null, // 如果需要存储图表相关的数据
      ShowMap: true,
    };
  },
  mounted() {
    // 注册模块
    ChartJS.register(
      CategoryScale, // 注册类别轴
      LinearScale,   // 注册线性尺度（用于 Y 轴）
      BarElement,    // 注册条形图元素
      Title,         // 注册标题插件
      Tooltip,       // 注册工具提示插件
      Legend         // 注册图例插件
    );
    this.renderChart();
    this.fetchProjects();
    //this.fetchProjectData();  // 新增调用项目数据加载
    this.fetchSubSystemData();  // 新增调用子系统数据加载
  },
  beforeRouteUpdate(to, from, next) {
    this.showMap = false; // 销毁 MapContainer
    this.$nextTick(() => {
      this.showMap = true; // 重新加载 MapContainer
    });
    next();
  },
  watch: {
    items1: {
      handler() {
        this.renderChart();
        this.selectAll1 = this.items1.every(item => item.checked);
      },
      deep: true
    }
  },
  methods: {
    // 获取项目数据并处理折线图
    async fetchProjects() {
      const projects = await this.fetchProjectsData();
      const { datesForChart, countsForChart } = this.processProjectData(projects);
      this.drawLineChart(datesForChart, countsForChart);
    },

    async fetchProjectsData() {
      try {
        const response = await axios.get('http://localhost:9000/projectReport/getAll');
        if (response.data.code === 200) {
          return response.data.data;
        } else {
          console.error('数据加载失败:', response.data.message);
          return [];
        }
      } catch (error) {
        console.error('请求数据时发生错误:', error);
        return [];
      }
    },

    processProjectData(projects) {
      const dateCounts = [];
      let count = 0;
      const dates = Array.from(new Set(projects.map(project => project.evaluateTime))).sort();

      dates.forEach(date => {
        count = projects.filter(project => project.evaluateTime <= date).length;
        dateCounts.push([date, count]);
      });

      const datesForChart = dateCounts.map(item => item[0]);
      const countsForChart = dateCounts.map(item => item[1]);

      const totalProjects = projects.length;  // 获取所有项目的总数

      return { datesForChart, countsForChart };
    },

    drawLineChart(dates, counts) {
      const chartDom = this.$refs.lineChart;
      const myChart = echarts.init(chartDom);

      // 将日期转为时间戳，便于操作
      const timestamps = dates.map(date => new Date(date).getTime());

      // 计算开始和结束日期的时间戳
      const startDate = new Date(Math.min(...timestamps));
      const endDate = new Date(Math.max(...timestamps));

      // 生成从开始日期到结束日期的日期数组
      const allDates = [];
      for (let date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
        allDates.push(new Date(date).toISOString().split('T')[0]); // 获取每一天的日期，格式为 YYYY-MM-DD
      }

      // 为每一天创建一个与之对应的 count 值，若某日期没有数据，则计数为前一天的值
      const countsForDates = [];
      let lastCount = 0;  // 用于存储上一个有效的 count 值
      const filteredDates = [];  // 用来存储所有日期，用于 X 轴标签

      allDates.forEach(date => {
        const index = dates.indexOf(date); // 查找当前日期是否有数据
        if (index !== -1) {
          lastCount = counts[index]; // 如果有数据，更新 lastCount
          filteredDates.push(date);  // 如果有数据，则将该日期加入日期数组
        } else {
          filteredDates.push('');  // 如果没有数据，将该日期的标签置为空
        }
        countsForDates.push(lastCount); // 如果没有数据，使用 lastCount
      });

      // 动态计算y轴的最大值和最小值
      const maxCount = Math.max(...countsForDates);  // 计算最大值
      const minCount = Math.min(...countsForDates);  // 计算最小值

      // 根据最大值和最小值计算分割间隔
      const yAxisInterval = Math.ceil((maxCount - minCount) / 5);  // 划分为5个区间

      const option = {
        tooltip: {
          trigger: 'axis'
        },
        xAxis: {
          type: 'category',  // 类目轴（离散型）
          data: filteredDates, // 使用所有日期作为 X 轴的标签
          axisLabel: {
            rotate: 45,       // 旋转标签避免重叠
            formatter: (value) => value || ' ',  // 如果日期为空，显示空格
          },
          axisTick: {
            alignWithLabel: true
          },
        },
        yAxis: {
          type: 'value',
          min: minCount,  // 设置 y 轴的最小值
          max: maxCount,  // 设置 y 轴的最大值
          interval: yAxisInterval,  // 设置 y 轴的间隔
          axisLabel: {
            formatter: '{value}', // 显示整数
            interval: 0,          // 显示所有标签
          },
          splitNumber: 6,  // 纵轴分成6个区间
          minInterval: 1   // 强制纵轴标签为整数
        },
        series: [
          {
            data: countsForDates,   // 使用所有日期对应的计数数据
            type: 'line',
            smooth: true,
            lineStyle: {
              width: 3
            },
            itemStyle: {
              color: '#5470c6'
            }
          }
        ]
      };

      myChart.setOption(option);
    },

    // 全选框切换
    toggleAll() {
      this.items1.forEach(item => {
        item.checked = this.selectAll1;
      });
    },

    // 根据数量生成颜色
    getColorByQuantity(quantity) {
      const maxQuantity = 50;
      const minQuantity = 10;
      const intensity = Math.min(255, Math.max(0, Math.floor(((quantity - minQuantity) / (maxQuantity - minQuantity)) * 255)));
      return `rgb(${intensity}, ${255 - intensity}, 100)`;
    },

    renderChart() {
      const selectedItems = this.items1.filter(item => item.checked);
      const names = selectedItems.map(item => item.name);
      const numbers = selectedItems.map(item => item.number);

      const chart = echarts.init(this.$refs.chart);

      const option = {
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
        },
        xAxis: {
          type: 'value',
          name: '数量',
          axisLine: { show: true }
        },
        yAxis: {
          type: 'category',
          data: names,
          name: '水果',
          axisLine: { show: true }
        },
        series: [
          {
            name: '数量',
            type: 'bar',
            data: numbers,
            itemStyle: {
              color: (params) => this.getColorByQuantity(numbers[params.dataIndex])
            }
          }
        ]
      };

      chart.setOption(option);
    },


    async fetchSubSystemData() {
      try {
        // 获取项目数据
        const projectResponse = await axios.get('http://localhost:9000/projectReport/getAll');
        if (projectResponse.data.code === 200) {
          console.log('项目数据:', projectResponse.data);

          // 获取项目名称
          this.projectNames = projectResponse.data.data.map(project => project.reportName);
          console.log('项目名称列表:', this.projectNames);
        } else {
          console.error('项目数据加载失败:', projectResponse.data.message);
          return;
        }
      } catch (error) {
        console.error('获取项目数据失败:', error);
        return;
      }

      try {
        const subsystems = {};
        const totalProjects = this.projectNames.length;

        // 获取子系统数据
        for (let i = 1; i <= totalProjects; i++) {
          const subSystemResponse = await axios.get(`http://localhost:9000/subSystem/getByReportId?reportId=${i}`);

          console.log(`子系统数据 (${i}):`, subSystemResponse.data);

          if (Array.isArray(subSystemResponse.data.data)) {
            const projectSubsystems = subSystemResponse.data.data.map(subsystem => ({
              name: subsystem.name,
              expense: subsystem.expense,
            }));

            // 计算项目的总费用
            const totalExpense = projectSubsystems.reduce((sum, subsystem) => sum + subsystem.expense, 0);

            subsystems[this.projectNames[i - 1]] = {
              subsystems: projectSubsystems,
              totalExpense: totalExpense, // 保存项目总费用
            };
          } else {
            console.error(`子系统数据格式错误，项目 ID ${i} 的数据未按预期返回数组`);
          }
        }

        this.projectData = subsystems;
        console.log("子系统数据已加载:", this.projectData);

        // 更新条形图显示
        this.updateBarChart();

      } catch (error) {
        console.error('获取子系统数据失败:', error);
      }
    },


    updateBarChart() {
      // 获取项目名称列表
      const labels = Object.keys(this.projectData); // 项目名称
      const datasets = [];
      const colors = [
        'rgba(54, 162, 235, 0.5)', // 蓝色
        'rgba(75, 192, 192, 0.5)', // 绿色
        'rgba(255, 206, 86, 0.5)', // 黄色
        'rgba(153, 102, 255, 0.5)', // 紫色
        'rgba(255, 99, 132, 0.5)', // 红色
      ]; // 子系统和总费用的颜色可以循环使用

      // 遍历子系统和项目总费用，生成对应的 dataset
      const subsystemLabels = new Set();
      labels.forEach((project, projectIndex) => {
        const projectSubsystems = this.projectData[project].subsystems;

        // 子系统费用按名字单独统计，用来分组显示
        projectSubsystems.forEach((subsystem, subIndex) => {
          subsystemLabels.add(subsystem.name);

          // 确保每个子系统的费用对应到正确的项目位置
          const data = Array(labels.length).fill(0);
          data[projectIndex] = subsystem.expense;

          datasets.push({
            label: `${subsystem.name}`, // 子系统名称
            data, // 每个项目的子系统费用
            backgroundColor: colors[subIndex % colors.length], // 循环选择颜色
            borderColor: colors[subIndex % colors.length].replace('0.5', '1'), // 边框颜色
            borderWidth: 1, // 边框宽度
          });
        });

        // 添加项目总费用数据
        const totalExpenseData = Array(labels.length).fill(0);
        totalExpenseData[projectIndex] = this.projectData[project].totalExpense;

        datasets.push({
          label: `${project} 总费用`, // 总费用
          data: totalExpenseData, // 每个项目总费用
          backgroundColor: 'rgba(255, 159, 64, 0.5)', // 总费用的颜色
          borderColor: 'rgba(255, 159, 64, 1)', // 总费用边框
          borderWidth: 1,
        });
      });

      // 获取 canvas 元素并初始化图表
      const ctx = document.getElementById('myChart').getContext('2d');
      new ChartJS(ctx, {
        type: 'bar', // 图表类型为条形图
        data: {
          labels: labels, // X 轴标签（项目名称）
          datasets: datasets, // 数据集（每个项目的子系统费用和总费用）
        },
        options: {
          responsive: true,
          plugins: {
            tooltip: {
              mode: 'index', // 鼠标悬浮时显示所有数据点
              intersect: false, // 不要求鼠标指针与数据点相交
            },
            legend: {
              display: true, // 显示图例
              position: 'top', // 图例位置
            },
          },
          scales: {
            x: {
              beginAtZero: true, // X 轴从零开始
              title: {
                display: false,
              },
              stacked: false, // 不堆叠，分开显示条形
              grid: {
                offset: true, // 确保条形对齐 X 轴标签
              },
              ticks: {
                padding: 20, // 设置 X 轴标签与下一个标签之间的间距（单位：像素）
              },
              barThickness: 30,       // 硬性设置条形宽度
              maxBarThickness: 40,    // 条形最大宽度
              categoryPercentage: 0.8, // 控制标签组宽度比例
              barPercentage: 0.9,     // 控制条形在组内宽度占比
            },
            y: {
              beginAtZero: true, // Y 轴从零开始
              title: {
                display: true,
                text: '费用 (单位)', // Y 轴标题
              },
            },
          },
        },
      });
    }
  }

};
</script>

<style scoped>
/* 全选框和水果项样式 */
.selectAll_check_box {
  margin-bottom: 20px;
  margin-right: 20px;
}

.no-bullets {
  list-style: none;
  padding: 0;
  margin: 0;
}

.no-bullets li {
  margin-bottom: 5px;
  padding: 3px 0;
  font-size: 16px;
}

label {
  font-size: 16px;
  cursor: pointer;
}

input[type="checkbox"] {
  margin-right: 10px;
}

/*调整地图位置*/
.mapShower {
  display: flex;
  flex-direction: column;
  /* 设置垂直方向排列，确保标题和地图在垂直方向 */
  justify-content: center;
  /* 垂直居中 */
  align-items: center;
  /* 水平居中 */
  height: 1010px;
  /* 设置父容器的高度为视口高度，确保居中 */
  margin-bottom: 80px;
  /* 也可以使用 margin 来增加间隔 */
}

h3 {
  margin-bottom: 20px;
  /* 为标题和地图之间添加间距 */
}

/*调整折线图*/
.number_data {
  display: flex;
  flex-direction: column;
  /* 设置垂直方向排列，确保标题和地图在垂直方向 */
  justify-content: center;
  /* 垂直居中 */
  align-items: center;
  /* 水平居中 */
  height: 800px;
  margin-bottom: 130px;
  /* 也可以使用 margin 来增加间隔 */
}

/* 父容器设置为 Flexbox，居中所有内容 */
.line_container {
  display: none;
  justify-content: center;
  /* 水平居中 */
  align-items: center;
  /* 垂直居中 */
  height: 1000px;
  /* 设置高度为视口高度 */
  width: 100%;
  /* 确保宽度占满屏幕 */
  margin-bottom: 80px;
  /* 也可以使用 margin 来增加间隔 */
}

/* 条形图容器，确保内容居中 */
.lineShower {
  display: none;
  flex-direction: column;
  justify-content: flex-start;
  /* 垂直方向对齐 */
  align-items: center;
  /* 水平居中 */
  width: 100%;
  /* 宽度占满父容器 */
  max-width: 1500px;
  /* 最大宽度限制 */
  margin: 0 auto;
  /* 自动左右外边距，确保居中 */
}

/* ECharts 容器 */
.lineShower_inner {
  display: none;
  justify-content: center;
  /* 水平居中 */
  align-items: center;
  /* 垂直居中 */
  width: 100%;
  /* 适应父容器宽度 */
  max-width: 1400px;
  /* 最大宽度限制 */
  height: 600px;
  /* 高度 */
}

.myChart_subSystem {
  display: flex;
  /* 使用 Flex 布局 */
  flex-direction: column;
  /* 元素垂直排列 */
  align-items: center;
  /* 水平居中对齐 */
  justify-content: center;
  /* 垂直方向适配 */
  height: 800px;
  /* 容器高度为视口高度 */
  margin-top: 100px;
  /* 距离顶部的间距 */
  margin-bottom: 100px;
}

.myChart_subSystem h3 {
  margin-bottom: 20px;
  /* 给标题和图表之间增加间距 */
  text-align: center;
  /* 标题文字居中对齐 */
}

#myChart {
  width: 10px;
  /* 图表宽度 */
  height: 500px;
  /* 图表高度 */
}
</style>
